package com.etu.jsonservices.exception;

import com.etu.jsonservices.dto.IDTO;
import com.etu.jsonservices.util.ResponseCodes;

/**
 * Basic error to be used directly by service commands.
 * 
 * @author uye
 * 
 */
@SuppressWarnings("serial")
public class InternalServerException extends Exception implements IDTO {

	/**
	 * Description of the error to be returned back to the client.
	 */
	private String errorDescription;
	/**
	 * Name of the failed service.
	 */
	private String serviceName = "unknown";

	/**
	 * Base constructor.
	 * 
	 * @param message
	 *            Error message
	 * @param cause
	 *            Parent exception
	 * @param serviceName
	 *            Name of the failed service
	 * 
	 */
	public InternalServerException(final String serviceName,
			final String message, final Throwable cause) {
		super(message, cause);
		initializeFields(serviceName);
	}

	/**
	 * Constructor for just wrapping another exception and no message.
	 * 
	 * @param message
	 *            Parent exception
	 * @param serviceName
	 *            Name of the failed service
	 */
	public InternalServerException(final String message,
			final Throwable cause) {
		super(message,cause);
		initializeFields(serviceName);
	}

	/**
	 * Constructor for associating a message with the exception.
	 * 
	 * @param message
	 *            Error message
	 * @param serviceName
	 *            Name of the failed service
	 */
	public InternalServerException(final String serviceName,
			final String message) {
		super(message);
		initializeFields(serviceName);
	}

	/**
	 * Basic constructor, setting the service name.
	 * 
	 * @param serviceName
	 *            Name of the failed service
	 */
	public InternalServerException(final String message) {
		super(message);
		initializeFields(serviceName);
	}

	/**
	 * Basic constructor accepting the stack trace.
	 * 
	 * @param cause
	 *            Parent exception
	 */
	public InternalServerException(final Throwable cause) {
		super(cause);
		initializeFields(serviceName);
	}

	/**
	 * Helper method to help initialize the class' fields. Also responsible for
	 * retrieving and setting the description associated with the error code. If
	 * none has been set, uses the unknown error description.
	 * 
	 * @param serviceName
	 *            name of the failed service
	 * @param errorCode
	 *            associated error code
	 */
	public void initializeFields(String serviceName) {
		this.serviceName = serviceName;

		if (ResponseCodes.hasDescription(getErrorCode())) {
			this.errorDescription = ResponseCodes
					.getDescription(getErrorCode());
		} else {
			this.errorDescription = ResponseCodes.getDescription("-1");
		}
	}

	/**
	 * Get the associated error code for this Exception.
	 * 
	 * @return The error code
	 */
	public String getErrorCode() {
		return ResponseCodes.BASE_ERROR_CODES.ERROR_500.toString();
	}

	/**
	 * Get the associated error description set for the error code.
	 * 
	 * @return The error message described for the error code in the properties
	 *         file
	 */
	public String getErrorDescription() {
		return errorDescription;
	}

	/**
	 * Get the service name that created this exception.
	 * 
	 * @return Name of the failed service.
	 */
	public String getServiceName() {
		return serviceName;
	}

	/**
	 * Sets the service name that created this exception.
	 * 
	 * @param serviceName
	 *            Name of the failed service.
	 */
	public void setServiceName(final String serviceName) {
		this.serviceName = serviceName;
	}

}
